Skip to main content

πŸ” EKS IRSA (IAM Roles for Service Accounts) – S3 Read‑Only Access Guide

This guide shows how to securely allow a Kubernetes pod running on Amazon EKS to read data from an S3 bucket using IAM Roles for Service Accounts (IRSA) β€” without hard‑coding AWS credentials. πŸš€


πŸͺœ Step 1: Get Your OIDC Provider for EKS​

First, find the OIDC issuer URL for your EKS cluster:

aws eks describe-cluster \
--name <your-cluster-name> \
--query "cluster.identity.oidc.issuer" \
--output text

πŸ“€ Output example:

https://oidc.eks.me-south-1.amazonaws.com/id/ABCDEF1234567890

πŸ” Verify OIDC Provider Exists in IAM​

aws iam list-open-id-connect-providers | grep ABCDEF1234567890

βœ… If you see output β†’ OIDC is already configured

❌ If you don’t see it β†’ create it using eksctl

eksctl utils associate-iam-oidc-provider \
--cluster <your-cluster-name> \
--approve

πŸͺœ Step 2: Create an IAM Policy for S3 Access​

Create a policy file named s3-access-policy.json:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::aiops-loadtest-reports"
},
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::aiops-loadtest-reports/*"
}
]
}

πŸ›‘οΈ Scope:

  • Read‑only access
  • Only for one bucket

βž• Create the IAM Policy​

aws iam create-policy \
--policy-name AIOpsLoadTestS3Access \
--policy-document file://s3-access-policy.json

πŸ“Œ Save the Policy ARN from the output β€” you’ll need it next.


πŸͺœ Step 3: Create an IAM Role for the Kubernetes Service Account​

The easiest and safest way is using eksctl:

eksctl create iamserviceaccount \
--name loadtest-viewer-sa \
--namespace default \
--cluster <your-cluster-name> \
--attach-policy-arn arn:aws:iam::<your-account-id>:policy/AIOpsLoadTestS3Access \
--approve \
--override-existing-serviceaccounts

βœ… What This Does​

  • 🧾 Creates a Kubernetes ServiceAccount: loadtest-viewer-sa
  • πŸ” Creates an IAM Role with trust to EKS OIDC
  • πŸ”— Attaches the S3 read‑only policy
  • πŸͺ Automatically annotates the ServiceAccount

πŸͺœ Step 4: Reference the Service Account in Deployment YAML​

Update your Deployment manifest to use the ServiceAccount:

apiVersion: apps/v1
kind: Deployment
metadata:
name: loadtest-viewer
spec:
replicas: 1
selector:
matchLabels:
app: loadtest-viewer
template:
metadata:
labels:
app: loadtest-viewer
spec:
serviceAccountName: loadtest-viewer-sa # πŸ‘ˆ IRSA enabled here
containers:
- name: loadtest-viewer
image: <your-ecr-repo-url>:latest
ports:
- containerPort: 8080
env:
- name: AWS_REGION
value: "me-south-1"
- name: S3_BUCKET
value: "aiops-loadtest-reports"

🚫 No access keys required


πŸͺœ Step 5: Deploy the Application​

kubectl apply -f deployment.yaml

Verify:

kubectl get pods

πŸͺœ Step 6: Verify the IAM Role Inside the Pod​

Exec into the running pod:

kubectl exec -it <pod-name> -- bash

Check if AWS credentials are injected automatically:

curl 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI

πŸ“€ You should see temporary credentials (AccessKeyId, Token, Expiration).


πŸ§ͺ Step 7: Test S3 Access from Inside the Pod​

If AWS CLI is installed:

aws s3 ls s3://aiops-loadtest-reports

Or using SDK in your app:

  • βœ… List objects
  • βœ… Download reports
  • ❌ Upload or delete (blocked by policy)

🧠 Common Troubleshooting​

❌ AccessDenied

  • Check ServiceAccount name
  • Verify IAM policy attachment
  • Ensure pod is restarted after SA creation

❌ No credentials found

  • OIDC provider missing
  • Wrong cluster name

🏁 Final Summary​

ComponentPurpose
πŸ” IRSASecure AWS access without secrets
πŸͺ OIDC ProviderTrust between EKS & IAM
🧾 IAM PolicyFine‑grained S3 permissions
πŸ§‘β€πŸ’» ServiceAccountIdentity for pods
πŸ“¦ PodUses AWS permissions safely

βœ… This setup is production‑grade, secure, and AWS‑recommended.